import 'dart:io';
import 'package:sqflite/sqflite.dart';
import 'package:logger/logger.dart';
import 'package:path/path.dart' as path;
import '../core/database_helper.dart';
import '../core/app_config.dart';

/// 系统设置服务
class SystemSettingsService {
  static final _logger = Logger();
  final DatabaseHelper _dbHelper = DatabaseHelper();

  /// 获取系统信息
  Future<Map<String, dynamic>> getSystemInfo() async {
    try {
      _logger.d('开始获取系统信息');
      
      final db = await _dbHelper.database;
      final dbPath = await _dbHelper.databasePath;
      final dbFile = File(dbPath);
      
      final info = {
        'app_name': AppConfig.appName,
        'app_version': AppConfig.appVersion,
        'database_path': dbPath,
        'database_size': dbFile.existsSync() ? dbFile.lengthSync() : 0,
        'database_version': await _getDatabaseVersion(db),
        'record_count': await _getRecordCount(db),
        'user_count': await _getUserCount(db),
        'last_backup': await _getLastBackupTime(),
        'system_uptime': DateTime.now().difference(DateTime(2024, 1, 1)).inDays,
      };
      
      _logger.i('系统信息获取成功');
      return info;
    } catch (e, stackTrace) {
      _logger.e('获取系统信息失败', error: e, stackTrace: stackTrace);
      rethrow;
    }
  }

  /// 备份数据库
  Future<String> backupDatabase() async {
    try {
      _logger.d('开始备份数据库');
      
      final dbPath = await _dbHelper.databasePath;
      final dbFile = File(dbPath);
      
      if (!dbFile.existsSync()) {
        throw Exception('数据库文件不存在');
      }
      
      // 创建备份目录
      final backupDir = Directory(path.join(path.dirname(dbPath), 'backups'));
      if (!backupDir.existsSync()) {
        await backupDir.create(recursive: true);
      }
      
      // 生成备份文件名
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      final backupFileName = 'backup_$timestamp.db';
      final backupPath = path.join(backupDir.path, backupFileName);
      
      // 复制数据库文件
      await dbFile.copy(backupPath);
      
      // 记录备份信息
      await _recordBackupInfo(backupPath, timestamp);
      
      _logger.i('数据库备份成功: $backupPath');
      return backupPath;
    } catch (e, stackTrace) {
      _logger.e('数据库备份失败', error: e, stackTrace: stackTrace);
      rethrow;
    }
  }

  /// 还原数据库
  Future<bool> restoreDatabase(String backupPath) async {
    try {
      _logger.d('开始还原数据库: $backupPath');
      
      final backupFile = File(backupPath);
      if (!backupFile.existsSync()) {
        throw Exception('备份文件不存在: $backupPath');
      }
      
      final dbPath = await _dbHelper.databasePath;
      final dbFile = File(dbPath);
      
      // 关闭数据库连接
      final db = await _dbHelper.database;
      await db.close();
      
      // 备份当前数据库（以防还原失败）
      final currentBackupPath = '${dbPath}_backup_${DateTime.now().millisecondsSinceEpoch}';
      if (dbFile.existsSync()) {
        await dbFile.copy(currentBackupPath);
        _logger.i('当前数据库已备份到: $currentBackupPath');
      }
      
      // 复制备份文件到数据库位置
      await backupFile.copy(dbPath);
      
      // 重新初始化数据库连接
      await _dbHelper.database;
      
      _logger.i('数据库还原成功');
      return true;
    } catch (e, stackTrace) {
      _logger.e('数据库还原失败', error: e, stackTrace: stackTrace);
      rethrow;
    }
  }

  /// 获取备份列表
  Future<List<Map<String, dynamic>>> getBackupList() async {
    try {
      _logger.d('开始获取备份列表');
      
      final dbPath = await _dbHelper.databasePath;
      final backupDir = Directory(path.join(path.dirname(dbPath), 'backups'));
      
      if (!backupDir.existsSync()) {
        return [];
      }
      
      final backupFiles = backupDir.listSync()
          .where((entity) => entity is File && entity.path.endsWith('.db'))
          .cast<File>()
          .toList();
      
      final backupList = <Map<String, dynamic>>[];
      
      for (final file in backupFiles) {
        final stat = file.statSync();
        final fileName = path.basename(file.path);
        final timestamp = _extractTimestampFromFileName(fileName);
        
        backupList.add({
          'file_path': file.path,
          'file_name': fileName,
          'file_size': stat.size,
          'created_time': DateTime.fromMillisecondsSinceEpoch(stat.modified.millisecondsSinceEpoch),
          'timestamp': timestamp,
        });
      }
      
      // 按时间倒序排列
      backupList.sort((a, b) => (b['timestamp'] as int).compareTo(a['timestamp'] as int));
      
      _logger.i('备份列表获取成功: ${backupList.length} 个备份');
      return backupList;
    } catch (e, stackTrace) {
      _logger.e('获取备份列表失败', error: e, stackTrace: stackTrace);
      rethrow;
    }
  }

  /// 删除备份
  Future<bool> deleteBackup(String backupPath) async {
    try {
      _logger.d('开始删除备份: $backupPath');
      
      final backupFile = File(backupPath);
      if (!backupFile.existsSync()) {
        throw Exception('备份文件不存在: $backupPath');
      }
      
      await backupFile.delete();
      
      _logger.i('备份删除成功: $backupPath');
      return true;
    } catch (e, stackTrace) {
      _logger.e('删除备份失败', error: e, stackTrace: stackTrace);
      rethrow;
    }
  }

  /// 清理旧备份
  Future<int> cleanupOldBackups({int keepCount = 10}) async {
    try {
      _logger.d('开始清理旧备份，保留数量: $keepCount');
      
      final backupList = await getBackupList();
      
      if (backupList.length <= keepCount) {
        _logger.i('备份数量未超过限制，无需清理');
        return 0;
      }
      
      final toDelete = backupList.skip(keepCount).toList();
      int deletedCount = 0;
      
      for (final backup in toDelete) {
        try {
          await deleteBackup(backup['file_path']);
          deletedCount++;
        } catch (e) {
          _logger.w('删除备份失败: ${backup['file_path']}, 错误: $e');
        }
      }
      
      _logger.i('旧备份清理完成，删除了 $deletedCount 个备份');
      return deletedCount;
    } catch (e, stackTrace) {
      _logger.e('清理旧备份失败', error: e, stackTrace: stackTrace);
      rethrow;
    }
  }

  /// 获取数据库版本
  Future<int> _getDatabaseVersion(Database db) async {
    try {
      final result = await db.rawQuery('PRAGMA user_version');
      return result.first['user_version'] as int? ?? 0;
    } catch (e) {
      _logger.w('获取数据库版本失败: $e');
      return 0;
    }
  }

  /// 获取记录数量
  Future<int> _getRecordCount(Database db) async {
    try {
      final result = await db.rawQuery('SELECT COUNT(*) as count FROM carbon_footprint_records WHERE is_deleted = 0');
      return result.first['count'] as int? ?? 0;
    } catch (e) {
      _logger.w('获取记录数量失败: $e');
      return 0;
    }
  }

  /// 获取用户数量
  Future<int> _getUserCount(Database db) async {
    try {
      final result = await db.rawQuery('SELECT COUNT(*) as count FROM users WHERE is_deleted = 0');
      return result.first['count'] as int? ?? 0;
    } catch (e) {
      _logger.w('获取用户数量失败: $e');
      return 0;
    }
  }

  /// 获取最后备份时间
  Future<DateTime?> _getLastBackupTime() async {
    try {
      final backupList = await getBackupList();
      if (backupList.isEmpty) {
        return null;
      }
      return backupList.first['created_time'] as DateTime?;
    } catch (e) {
      _logger.w('获取最后备份时间失败: $e');
      return null;
    }
  }

  /// 记录备份信息
  Future<void> _recordBackupInfo(String backupPath, int timestamp) async {
    try {
      final db = await _dbHelper.database;
      await db.insert('backup_logs', {
        'backup_path': backupPath,
        'backup_time': timestamp,
        'file_size': File(backupPath).lengthSync(),
        'created_at': DateTime.now().toIso8601String(),
      });
    } catch (e) {
      _logger.w('记录备份信息失败: $e');
    }
  }

  /// 从文件名提取时间戳
  int _extractTimestampFromFileName(String fileName) {
    try {
      final match = RegExp(r'backup_(\d+)\.db').firstMatch(fileName);
      if (match != null) {
        return int.parse(match.group(1)!);
      }
    } catch (e) {
      _logger.w('从文件名提取时间戳失败: $e');
    }
    return 0;
  }

  /// 验证备份文件
  Future<bool> validateBackup(String backupPath) async {
    try {
      _logger.d('开始验证备份文件: $backupPath');
      
      final backupFile = File(backupPath);
      if (!backupFile.existsSync()) {
        return false;
      }
      
      // 尝试打开备份数据库
      final backupDb = await openDatabase(backupPath, readOnly: true);
      
      // 检查表结构
      final tables = await backupDb.rawQuery("SELECT name FROM sqlite_master WHERE type='table'");
      final tableNames = tables.map((row) => row['name'] as String).toList();
      
      // 检查必要的表是否存在
      final requiredTables = ['users', 'carbon_footprint_records', 'process_types'];
      final hasAllTables = requiredTables.every((table) => tableNames.contains(table));
      
      await backupDb.close();
      
      _logger.i('备份文件验证完成: ${hasAllTables ? '有效' : '无效'}');
      return hasAllTables;
    } catch (e, stackTrace) {
      _logger.e('验证备份文件失败', error: e, stackTrace: stackTrace);
      return false;
    }
  }

  /// 获取系统统计信息
  Future<Map<String, dynamic>> getSystemStatistics() async {
    _logger.d('开始获取系统统计信息');
    
    try {
      final db = await _dbHelper.database;
      
      // 用户统计
      final userStats = await db.rawQuery('''
        SELECT 
          COUNT(*) as total_users,
          SUM(CASE WHEN is_active = 1 THEN 1 ELSE 0 END) as active_users,
          SUM(CASE WHEN role = 2 THEN 1 ELSE 0 END) as admin_users
        FROM users 
        WHERE is_deleted = 0
      ''');
      
      // 记录统计
      final recordStats = await db.rawQuery('''
        SELECT 
          COUNT(*) as total_records,
          SUM(CASE WHEN record_date >= date('now', '-30 days') THEN 1 ELSE 0 END) as recent_records
        FROM carbon_footprint_records 
        WHERE is_deleted = 0
      ''');
      
      // 工艺类型统计
      final processStats = await db.rawQuery('''
        SELECT 
          pt.type_name as process_type,
          COUNT(cfr.id) as record_count
        FROM process_types pt
        LEFT JOIN carbon_footprint_records cfr ON pt.id = cfr.process_type AND cfr.is_deleted = 0
        WHERE pt.is_active = 1
        GROUP BY pt.id, pt.type_name
        ORDER BY record_count DESC
      ''');
      
      final result = {
        'user_statistics': userStats.first,
        'record_statistics': recordStats.first,
        'process_statistics': processStats.map((row) => {
          'process_type': (row['process_type'] as String?) ?? '未知工艺',
          'record_count': (row['record_count'] as int?) ?? 0,
        }).toList(),
      };
      
      _logger.i('系统统计信息获取成功');
      return result;
    } catch (e) {
      _logger.e('获取系统统计信息失败: $e');
      rethrow;
    }
  }

  /// 重置测试数据
  Future<void> resetTestData() async {
    _logger.d('开始重置测试数据');
    
    try {
      await _dbHelper.resetTestData();
      _logger.i('测试数据重置成功');
    } catch (e) {
      _logger.e('重置测试数据失败: $e');
      rethrow;
    }
  }

  /// 添加额外测试数据
  Future<void> addExtraTestData() async {
    _logger.d('开始添加额外测试数据');
    
    try {
      await _dbHelper.addExtraTestData();
      _logger.i('额外测试数据添加成功');
    } catch (e) {
      _logger.e('添加额外测试数据失败: $e');
      rethrow;
    }
  }

  /// 获取测试数据统计信息
  Future<Map<String, dynamic>> getTestDataStats() async {
    _logger.d('开始获取测试数据统计信息');
    
    try {
      final stats = await _dbHelper.getTestDataStats();
      _logger.i('测试数据统计信息获取成功');
      return stats;
    } catch (e) {
      _logger.e('获取测试数据统计信息失败: $e');
      rethrow;
    }
  }
} 